package com.cbdp.common.util;

import org.springframework.beans.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * com.yinghuo.risk.frigate.web.util
 *
 * @author 白雨浓
 * date: 2018/10/19 11:41
 * content: 模型转换
 */
public class BeanUtil {

    public static <T> T to(Object source, Class<T> cls) {

        T target;
        try {
            target = cls.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            throw new RuntimeException("convert fail");
        }
        BeanUtils.copyProperties(source, target);

        return target;
    }

    public static <S, T> T to(S source, Class<T> cls, Convert<S, T> convert) {

        T target;
        try {
            target = cls.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            throw new RuntimeException("convert fail");
        }
        BeanUtils.copyProperties(source, target);

        convert.convert(source, target);

        return target;
    }

    public static <T> List<T> to(List<?> sourceList, Class<T> cls) {
        List<T> targetList = new ArrayList<>(sourceList.size());

        for (Object source : sourceList) {
            T target = to(source, cls);
            targetList.add(target);
        }

        return targetList;
    }

    public static <S, T> List<T> to(List<S> sourceList, Class<T> cls, Convert<S, T> convert) {
        List<T> targetList = new ArrayList<>(sourceList.size());

        for (S source : sourceList) {
            T target = to(source, cls);
            convert.convert(source, target);
        }

        return targetList;
    }

    @FunctionalInterface
    public interface Convert<S, T> {

        void convert(S source, T target);

    }

}
